/* $Id: log.h jjs $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#ifndef __LOG_H
#define __LOG_H

/** \file log.h
    \brief Logging infrastructure

    Routines that can write usefull notes to a logfile.\n
    It's possible to enable logging for different modules of the program even during
    the runtime of the program. It's also possible to disable the more detailed logging
    code at compile time so there is no overhead in the final release from excessive log messages.
*/

/// Open the logfile
/**
When not called or on a failure stderr will be used for logging.
 \param file The logfile to open
*/
void dbg_init(const char *file);

/// Log something
/**
Prefer the marcro's above this function for smaller code on a low DEBUG_LEVEL
 \param prio the priority of this log message
 \param routine the routine where this code is a part of
 \param format a ANSI-C style format string
 \param ... parameters used with the format string
*/

void dbg_log(const int prio, const char *routine, const char *format, ...);

/// Set the debug level for a routine
/**
 \param prio The priority of messages that will be show, higher means more detailed logging.
 \param routine The debug name of the routine as defined at the start of the .cc file usually its name.\n
 A NULL will result in setting the general debug level for every routine that has no specific level set.
*/

void dbg_level(const int prio, const char *routine);

#define DEBUG_ERROR 0
#define DEBUG_STATE 1
#define DEBUG_COMM 2
#define DEBUG_DATA 3
#define DEBUG_CALLS 4

/// The perferred debug level written inside the code, higher than this level the code is omitted

#ifndef DEBUG_LEVEL
    #define DEBUG_LEVEL DEBUG_CALLS
#endif

#ifndef DEBUG_ROUTINE
    #define DEBUG_ROUTINE "unknown"
#endif

/// Send errors to the log

#define dbg_error(...) dbg_log(DEBUG_ERROR, DEBUG_ROUTINE, __VA_ARGS__)
#define dbg_fatal(...) { dbg_log(DEBUG_ERROR, DEBUG_ROUTINE, __VA_ARGS__); exit(1); }

/// Send debug messages about the program state

#if DEBUG_LEVEL >= DEBUG_STATE
    #define dbg_state(...) dbg_log(DEBUG_STATE, DEBUG_ROUTINE, __VA_ARGS__)
#else
    #define dgb_state(...)
#endif

/// Send debug messages about communication

#if DEBUG_LEVEL >= DEBUG_COMM
    #define dbg_comm(...) dbg_log(DEBUG_COMM, DEBUG_ROUTINE, __VA_ARGS__)
#else
    #define dbg_comm(...)
#endif

/// Send debug messages about changes to data

#if DEBUG_LEVEL >= DEBUG_DATA
    #define dbg_data(...) dbg_log(DEBUG_DATA, DEBUG_ROUTINE, __VA_ARGS__)
#else
    #define dbg_data(...)
#endif

/// Send debug messages about calls to functions

#if DEBUG_LEVEL >= DEBUG_CALLS
    #define dbg_calls(...) dbg_log(DEBUG_CALLS, DEBUG_ROUTINE, __VA_ARGS__)
#else
    #define dbg_calls(...)
#endif

#endif // __LOG_H
